﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<vector>
#include<iostream>
using namespace std;

//class Person
//{
//public:
//	// 进入校园/图书馆/实验室刷二维码等身份认证
//	void identity()
//	{
//		cout << "void identity()" << _name << endl;
//	}
//protected:
//	string _name = "张三"; // 姓名
//	string _address; // 地址
//	string _tel; // 电话
//	int _age = 18; // 年龄
//};
//
//class Student : public Person
//{
//public:
//	// 学习
//	void study()
//	{
//		//...
//		identity();
//	}
//protected:
//	int _stuid; // 学号
//};
//
//class Teacher : public Person
//{
//public:
//	// 授课
//	void teaching()
//	{
//		//...
//	}
//protected:
//	string title; // 职称
//};
//
//int main()
//{
//	Student s;
//	Teacher t;
//
//	s.identity();
//	t.identity();
//
//	return 0;
//}

////栈继承顺序表
//namespace egoist
//{
//	template<class T>
//	class Stack : public std::vector<T>
//	{
//	public:
//		void Push(const T& x)
//		{
//			// 基类是类模板时，需要指定一下类域，
//			// 否则编译报错:error C3861: “push_back”: 找不到标识符
//			// 因为stack<int>实例化时，也实例化vector<int>了
//			// 但是模版是按需实例化，push_back等成员函数未实例化，所以找不到
//			vector<T>::push_back(x);
//		}
//
//		void Pop()
//		{
//			vector<T>::pop_back();
//		}
//
//		int Top()
//		{
//			return vector<T>::back();
//		}
//	};
//}
//
//int main()
//{
//	egoist::Stack<int> s1;
//	s1.push_back(1);
//	s1.Push(2);
//	auto it = s1.begin();
//	while (!s1.empty())
//	{
//		cout << s1.Top() << " ";
//		s1.Pop();
//	}
//	return 0;	
//}

/////////////////////////////////////////////////////////////////////////////

//class Person
//{
//public:
//	void Print()
//	{
//		cout << _name << endl;
//		cout << _age << endl;
//	}
//
//protected:
//	string _name = "张三";//姓名
//
//private:
//	int _age = 18;//年龄
//};
//
//class Student : public Person
//{
//public:
//	void study()
//	{
//		cout << _name << endl;
//		//cout << _age << endl;//不可见
//		Print();
//	}
//protected:
//	int _stuid;//学号
//};
//
//int main()
//{
//	Student s1;
//	s1.study();
//	s1.Print();
//	//s1._name;//保护
//	return 0;
//}


//class Person
//{
//protected:
//	string _name = "张三"; // 姓
//	int _id = 1;
//};
//
//class Student : public Person
//{
//public:
//	void func()
//	{
//		cout << _id << endl;
//	}
//protected:
//	int _stunum = 1; // 学号
//	int _id = 2;
//};
//
//int main()
//{
//	Student s;
//	//切片
//	Person* ptr = &s;//这里是不会报错的，不涉及类型转换，可以认为是编译器做了对这个有特殊处理，是指向的是子类当中切出来的父类的那一部分 Person* =Student*
//	Person& ref = s;//这里同样不涉及类型转换，赋值的时候会产生临时对象，临时对象具有常性，正常来讲应该用const修饰，但这里是一个特殊处理，ref引用的是子类当中切出来的父类的那一部分
//
//	//int i = 1;
//	//const double& d = i;
//	return 0;
//}


//class Person
//{
//protected:
//	int _id = 1;
//};
//
//class Student : public Person
//{
//public:
//	void Print()
//	{
//		cout << Person::_id << endl;//由于_id中在父类和子类中都有重名，涉及到隐藏概念，会对父类_id进行屏蔽,要想访问需要指定
//		cout << _id << endl;
//	}
//protected:
//	int _id = 2;
//};
//
//int main()
//{
//	Student s;
//	s.Print();
//	return 0;
//}


//class A
//{
//public:
//	//与子类重名且参数不同是重载吗？不是，不在同一作用域中，构成隐藏
//	void func()
//	{
//		cout << "func()" << endl;
//	}
//};
//
//class B : public A
//{
//public:
//	void func(int i)
//	{
//		cout << "func(int i)" << endl;
//	}
//};
//
//int main()
//{
//	B b;
//	b.func(1);
//	//b.func();//我们期望调用父类的func,但是由于子类和父类的函数重名，构成隐藏，会对父类的func进行屏蔽，因此需要指定类域才可以实现
//	b.A::func();
//	return 0;
//}


//class Person
//{
//public:
//	//Person(const char* name = "egoist")
//	Person(const char* name)
//		:_name(name)
//	{
//		cout << "Person()" << endl;
//	}
//
//	Person(const Person& p)
//		:_name(p._name)
//	{
//		cout << "Person(const Person& p)" << endl;
//	}
//
//	Person& operator=(const Person& p)
//	{
//		cout << "Person operator=(const Person& p)" << endl;
//		if (this != &p)
//		{
//			_name = p._name;
//		}
//		return *this;
//	}
//
//	~Person()
//	{
//		cout << "~Person()" << endl;
//	}
//
//protected:
//	string _name; // 姓名
//};
//
//
////子类中父类成员变量当成整体对象，作为子类自定义类型成员看待
//class Student : public Person
//{
//public:
//	////报错
//	//Student(const char* name, int num)
//	//	:_name(name)
//	//	,_num(num)
//	//{}
//
//	//派⽣类的构造函数必须调⽤基类的构造函数初始化基类的那⼀部分成员,如果基类没有默认构造，那么派生类就需要显式调用
//	Student(const char* name,int num)
//		:Person(name) 
//		,_num(num)
//	{}
//
//	Student(const Student& p)
//		:Person(p)  //--> 切片 ，切出父类的那一部分
//		,_num(p._num)
//	{
//		//实现深拷贝...
//	}
//
//	Student& operator=(const Student& s)
//	{
//		// 深拷贝 需要自己写，否则默认生成的就可以够了
//		if (this != &s)
//		{
//			//由于operator=构成隐藏，需要指定作用域
//			Person::operator=(s);
//			_num = s._num;
//		}
//		return *this;
//	}
//
//	~Student()
//	{
//		//~Person();//err,虽然Student和Person看似不构成重载，但是析构后面会处理成destructor()，构成隐藏，因此会报错
//		
//		//// 不需要显示调用，保证析构时，先子后父
//		//Person::~Person();
//		delete[] _ptr;
//
//		// 派生类析构结束后，自动调用父类的析构
//	}
//
//protected:
//	int _num = 1; //学号
//
//	//int* _ptr; //含有资源申请时，需要深拷贝之类的就需要显式写拷贝
//	int* _ptr = new int[10];
//};
//
//int main()
//{
//	Student s1("Peter", 1);
//	//Student s2 = s1;
//	//Student s3("Jay", 2);
//	//s1 = s3;
//	return 0;
//}


//class Base final//final不能被继承(C++11)
//{
//public:
//	void func5() { cout << "Base::func5" << endl; }
//protected:
//	int a = 1;
//private:
//	// C++98的方法
//	Base()
//	{}
//};
//
//class Derive :public Base
//{
//	void func4() { cout << "Derive::func4" << endl; }
//protected:
//	int b = 2;
//};
//
//int main()
//{
//	Derive d;//C++98让其实例化不出对象
//
//	return 0;
//}


////前置声明
//class Student;
//
//class Person
//{
//public:
//	friend void Display(const Person& x, const Student& y); //相互引用
//private:
//	string _name = "Peter";//姓名
//};
//
//class Student : public Person
//{
//public:
//	friend void Display(const Person& x, const Student& y);
//private:
//	int _stuid = 1;//学号
//};
//
//void Display(const Person& x, const Student& y)
//{
//	cout << x._name << endl;
//	cout << y._stuid << endl;
//}
//
//int main()
//{
//	Student s1;
//	Person p1;
//	Display(p1,s1);
//	return 0;
//}


//class Person
//{
//public:
//	string _name = "Peter";
//	static int _id;
//};
//
//int Person::_id = 1;
//
//class Student : public Person
//{
//private:
//	string _address;
//};
//
//int main()
//{
//	Person p1;
//	Student s1;
//	//占据空间不同
//	cout << &p1._name << endl;
//	cout << &s1._name << endl;
//
//	//占据同一块内存
//	cout << &p1._id << endl;
//	cout << &s1._id << endl;
//	return 0;
//}


//菱形继承
class Person
{
public:
	string _name;
};

class Student : virtual public Person //虚继承
{
protected:
	int _num; //学号
};

class Teacher : virtual public Person
{
protected:
	int _id; // 职工编号
};

class assistant :public Student, public Teacher
{
protected:
	string _majorCourse; // 主修课程
};

int main()
{
	assistant a;
	////error C2385: 对“_name”的访问不明确 --> 有两份_name
	a._name = "Peter";

	//需要指定
	//a.Student::_name = "Peter";
	//a.Teacher::_name = "张三";
	return 0;
}